﻿using System;
using System.Drawing;
using System.Windows.Forms;
using GeoSketch2.Core;

namespace GeoSketch2.Archaeo
{
    public partial class LayersManager : Form
    {
        #region Fields
        //The current viewport
        Viewport Viewport;

        //The current excavation area (can be site, square or unit)
        ExcavationArea CurrentExcavationArea;

        //The active drawing form
        DrawingForm DrawingForm;

        const int ColIndexCurrentLayer = 0;
        const int ColIndexLayerName = 1;
        const int ColIndexLayerColor = 2;
        const int ColIndexLayerLineType = 3;
        const int ColIndexAvailableLayer = 4;
        const int ColIndexVisibleLayer = 5;
        const int ColIndexLayerObject = 6;

        string[] LineTypeList;
        #endregion

        #region Constructor
        /// <summary>
        /// A layer manager for the Archaeomodule (because of the available layers)
        /// </summary>
        /// <param name="MDIParentForm">The parent form</param>
        /// <param name="Viewport">The current viewport</param>
        /// <param name="DrawingForm">The drawing form</param>
        public LayersManager(Form MDIParentForm, Viewport Viewport, DrawingForm DrawingForm)
            //: base(new ActiveMDIParentItems(false), MDIParentForm)
        {
            InitializeComponent();
            ToolStripManager.RevertMerge(((GeoSketchMainForm)MDIParentForm).ParentToolbar);

            this.Viewport = Viewport;
            this.CurrentExcavationArea = Viewport.CurrentExcavationArea;
            this.DrawingForm = DrawingForm;

            LineTypeList = new string[Viewport.LineTypeLibrary.Count];

            for (int i = 0; i < LineTypeList.Length; i++)
            {
                LineTypeList[i] = i + " | " + Viewport.LineTypeLibrary[i];
            }

            LoadLayers();
            DataGrid.CellClick += new DataGridViewCellEventHandler(DataGrid_CellClick);
        }
        #endregion

        #region Events
        private void DataGrid_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            DataGridViewCell CurrentCell = (DataGridViewCell)((DataGridView)sender).CurrentCell;
            Layer CurrentLayer = (Layer)(DataGrid[ColIndexLayerObject, CurrentCell.RowIndex].Value);

            if (CurrentLayer == null)
            {
                CurrentLayer = new Layer("NewLayer" + CurrentCell.RowIndex, Color.Black, new LineType(), true);
                DataGrid[ColIndexCurrentLayer, CurrentCell.RowIndex].Value = false;
                DataGrid[ColIndexLayerName, CurrentCell.RowIndex].Value = CurrentLayer.Name;
                DataGrid[ColIndexLayerColor, CurrentCell.RowIndex].Value = CurrentLayer.MenuItemImageVisible;
                DataGrid[ColIndexLayerLineType, CurrentCell.RowIndex].Value = null;
                DataGrid[ColIndexAvailableLayer, CurrentCell.RowIndex].Value = true;
                DataGrid[ColIndexVisibleLayer, CurrentCell.RowIndex].Value = CurrentLayer.Visible;
                DataGrid[ColIndexLayerObject, CurrentCell.RowIndex].Value = CurrentLayer;
                ((DataGridViewComboBoxCell)DataGrid[ColIndexLayerLineType, CurrentCell.RowIndex]).Items.AddRange(LineTypeList);
                DataGrid.Update();
            }

            switch (CurrentCell.ColumnIndex)
            {
                case ColIndexCurrentLayer:
                    for (int i = 0; i < DataGrid.RowCount - 1; i++)
                    {
                        DataGrid[ColIndexCurrentLayer, i].Value = false;
                    }
                    CurrentCell.Value = true;
                    break;
                case ColIndexLayerColor:
                    ColorDialog cd = new ColorDialog();
                    DialogResult dr = cd.ShowDialog();
                    if (dr == DialogResult.OK)
                    {
                        CurrentCell.Value = Tools.GetColoredSquare(cd.Color, Core.Vars.Setup.StandardObjects.Layer.MenuItemsImageSize);
                        DataGrid.Update();
                    }
                    break;
            }
        }

        private void Button_OK_Click(object sender, EventArgs e)
        {
            SaveChanges();
            DrawingForm.LoadLayers();
            DrawingForm.LoadColors();
            DrawingForm.MergeToolbars();
            this.Close();
        }

        private void Button_Cancel_Click(object sender, EventArgs e)
        {
            DrawingForm.MergeToolbars();
            this.Close();
        }

        private void Button_Up_Click(object sender, EventArgs e)
        {
            int CurrentRow = DataGrid.CurrentRow.Index;
            SwitchRows(CurrentRow, CurrentRow - 1);
            DataGrid.Update();
        }

        private void Button_Down_Click(object sender, EventArgs e)
        {
            int CurrentRow = DataGrid.CurrentRow.Index;
            SwitchRows(CurrentRow, CurrentRow + 1);
            DataGrid.Update();
        }

        private void Button_MoveToTop_Click(object sender, EventArgs e)
        {
            int CurrentRow = DataGrid.CurrentRow.Index;
            for (int i = CurrentRow; i > 0; i--)
            {
                SwitchRows(i, i-1);
            }
            DataGrid.Update();
        }

        private void Button_Bottom_Click(object sender, EventArgs e)
        {
            int CurrentRow = DataGrid.CurrentRow.Index;
            for (int i = CurrentRow; i < DataGrid.RowCount-2; i++)
            {
                SwitchRows(i, i+1);
            }
            DataGrid.Update();
        }
        #endregion

        #region Methods
        private void LoadLayers()
        {
            int CurrentRowIndex = 0;

            Viewport.Layers.Sort(Layer.CompareLayerDisplayOrderDesc);
            foreach (Layer layer in Viewport.Layers)
            {
                DataGrid.Rows.Add(new object[]{
                    layer.Name == Viewport.CurrentLayer.Name,
                    layer.Name,
                    layer.MenuItemImageVisible,
                    null,
                    CurrentExcavationArea.AvailableLayers.Contains(layer),
                    layer.Visible,
                    layer
                });
                ((DataGridViewComboBoxCell)DataGrid[ColIndexLayerLineType, CurrentRowIndex]).Items.AddRange(LineTypeList);
                ((DataGridViewComboBoxCell)DataGrid[ColIndexLayerLineType, CurrentRowIndex]).Value = ((DataGridViewComboBoxCell)DataGrid[ColIndexLayerLineType, CurrentRowIndex]).Items[Viewport.LineTypeLibrary.IndexOf(layer.LineType)];
                CurrentRowIndex++;
            }
            Viewport.Layers.Sort(Layer.CompareLayerDisplayOrderAsc);
        }

        private void SaveChanges()
        {
            int TotalLayers = TotalLayerCount;
            Layer CurrentLayer;

            CurrentExcavationArea.AvailableLayers.Clear();
            Viewport.Layers.Clear();

            for (int i = 0; i < TotalLayers; i++)
            {
                CurrentLayer = (Layer)DataGrid[ColIndexLayerObject, i].Value;

                CurrentLayer.DisplayOrder = TotalLayers - i - 1;
                CurrentLayer.Name = DataGrid[ColIndexLayerName, i].EditedFormattedValue.ToString();
                CurrentLayer.LayerColor = Tools.GetBitmapColor((Bitmap)DataGrid[ColIndexLayerColor, i].Value);
                string [] LineTypeSplit=((string)(DataGrid[ColIndexLayerLineType, i].Value)).Split('|');
                CurrentLayer.LineType = Viewport.LineTypeLibrary[Convert.ToInt32(LineTypeSplit[0])];
                if ((bool)DataGrid[ColIndexAvailableLayer, i].Value) { CurrentExcavationArea.AvailableLayers.Add(CurrentLayer); }
                CurrentLayer.Visible = (bool)DataGrid[ColIndexVisibleLayer, i].Value;

                Viewport.Layers.Add(CurrentLayer);
                if ((bool)DataGrid[ColIndexCurrentLayer, i].Value) { Viewport.CurrentLayer = CurrentLayer; }
            }

            Viewport.SortLayers();
            Core.Vars.Setup.StandardObjects.Layer.NextAvailableDisplayOrder = TotalLayers;
            CurrentExcavationArea.SortLayers();
        }

        //The method to switch two rows, to change order
        private void SwitchRows(int FirstIndex, int SecondIndex)
        {
            object
                TempCurrentLayer = DataGrid[ColIndexCurrentLayer, FirstIndex].Value,
                TempName = DataGrid[ColIndexLayerName, FirstIndex].EditedFormattedValue.ToString(),
                TempImage = DataGrid[ColIndexLayerColor, FirstIndex].Value,
                TempLineType = DataGrid[ColIndexLayerLineType, FirstIndex].Value,
                TempAvailable = DataGrid[ColIndexAvailableLayer, FirstIndex].Value,
                TempVisible = DataGrid[ColIndexVisibleLayer, FirstIndex].Value,
                TempLayer = DataGrid[ColIndexLayerObject, FirstIndex].Value;

            DataGrid[ColIndexCurrentLayer, FirstIndex].Value = DataGrid[ColIndexCurrentLayer, SecondIndex].Value;
            DataGrid[ColIndexLayerName, FirstIndex].Value = DataGrid[ColIndexLayerName, SecondIndex].Value;
            DataGrid[ColIndexLayerColor, FirstIndex].Value = DataGrid[ColIndexLayerColor, SecondIndex].Value;
            DataGrid[ColIndexLayerLineType, FirstIndex].Value = DataGrid[ColIndexLayerLineType, SecondIndex].Value;
            DataGrid[ColIndexAvailableLayer, FirstIndex].Value = DataGrid[ColIndexAvailableLayer, SecondIndex].Value;
            DataGrid[ColIndexVisibleLayer, FirstIndex].Value = DataGrid[ColIndexVisibleLayer, SecondIndex].Value;
            DataGrid[ColIndexLayerObject, FirstIndex].Value = DataGrid[ColIndexLayerObject, SecondIndex].Value;

            DataGrid[ColIndexCurrentLayer, SecondIndex].Value = TempCurrentLayer;
            DataGrid[ColIndexLayerName, SecondIndex].Value = TempName;
            DataGrid[ColIndexLayerColor, SecondIndex].Value = TempImage;
            DataGrid[ColIndexLayerLineType, SecondIndex].Value = TempLineType;
            DataGrid[ColIndexAvailableLayer, SecondIndex].Value = TempAvailable;
            DataGrid[ColIndexVisibleLayer, SecondIndex].Value = TempVisible;
            DataGrid[ColIndexLayerObject, SecondIndex].Value = TempLayer;
        }
        #endregion

        #region Properties
        private int TotalLayerCount
        {
            get
            {
                int dst = DataGrid.RowCount;
                DataGridViewRow row = DataGrid.Rows[dst - 1]; 
                if (row.Cells[ColIndexLayerObject].Value == null)
                {
                    dst--;
                }
                return dst;
            }
        }
        #endregion
    }
}
